﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using SweeperPrototype.Business;
using SweeperPrototype.Business.Fields;
using SweeperPrototype.Business.Keys;
using WPFUtilities.Collections;

namespace SweeperPrototype.Objects
{
    public partial class PositionSubscription
    {
        private const int MAX_UPDATE_LOOKBACK = 50;

        private readonly ConcurrentQueue<PositionUpdate> m_UpdateStack;
        private readonly BookCode m_BookCode;
        private readonly ExposureRIC m_RIC;

        private PositionUpdate m_LastUpdate;

        public PositionSubscription(BookCode book_code, ExposureRIC ric)
        {
            m_UpdateStack = new ConcurrentQueue<PositionUpdate>();
            m_BookCode = book_code;
            m_RIC = ric;
        }

        public BookCode BookCode
        {
            get { return m_BookCode; }
        }

        public ExposureRIC RIC
        {
            get { return m_RIC; }
        }

        public Shares Quantity
        {
            get{ return m_LastUpdate == null ? null : m_LastUpdate.Quantity; }
        }

        public Timestamp UpdateTimestamp
        {
            get { return m_LastUpdate == null ? null : m_LastUpdate.Timestamp; }
        }


        public PositionUpdate LastUpdate
        {
            get { return m_LastUpdate; }
        }

        public bool IsValid
        {
            get
            {
#if DEBUG
                //return new Random().NextDouble() > .01;
                if (RIC.Value.EndsWith("0")) return false;
#endif
                return m_UpdateStack.Count != 0;
            }
        }

        public void Update( PositionUpdate update )
        {
            PositionUpdate previous = m_LastUpdate;
            m_LastUpdate = update;
            m_UpdateStack.Enqueue(previous);

            Updated(this, update, previous );
            
            if( m_UpdateStack.Count > MAX_UPDATE_LOOKBACK )
            {
                PositionUpdate dequeued;
                while( m_UpdateStack.TryDequeue( out dequeued) == false ) {}
            }
        }

        public event UpdateDelegate<PositionSubscription, PositionUpdate> Updated = delegate { };
    }
}